package com.szcinda.rpa.service;

import com.szcinda.rpa.repository.JobDetail;
import com.szcinda.rpa.repository.JobDetailRepository;
import com.szcinda.rpa.repository.OrderFile;
import com.szcinda.rpa.repository.OrderFileRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.io.File;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class JobDetailServiceImpl implements JobDetailService {

    private final JobDetailRepository jobDetailRepository;
    private final OrderFileRepository orderFileRepository;
    private final SnowFlakeFactory snowFlakeFactory;

    public JobDetailServiceImpl(JobDetailRepository jobDetailRepository, OrderFileRepository orderFileRepository) {
        this.jobDetailRepository = jobDetailRepository;
        this.orderFileRepository = orderFileRepository;
        this.snowFlakeFactory = SnowFlakeFactory.getInstance();
    }

    @Override
    public void create(JobDetailCreateDto jobDetail) {
        JobDetail jobDe = jobDetailRepository.findByOrderNoAndJobName(jobDetail.getOrderNo(), jobDetail.getJobName());
        if (jobDe == null) {
            jobDe = new JobDetail();
            BeanUtils.copyProperties(jobDetail, jobDe);
            jobDe.setId(snowFlakeFactory.nextId());
            jobDetailRepository.save(jobDe);
        }
        OrderFile file;
        for (JobDetailCreateDto.File inFile : jobDetail.getInFiles()) {
            file = new OrderFile();
            file.setId(snowFlakeFactory.nextId());
            file.setOrderId(jobDe.getId());
            file.setFileName(inFile.getFileName());
            file.setOriginalFileName(inFile.getOriginalFileName());
            file.setType("IN");
            file.setUuidName(inFile.getUuidName());
            file.setAbsPath(inFile.getAbsPath());
            orderFileRepository.save(file);
        }
        for (JobDetailCreateDto.File outFile : jobDetail.getOutFiles()) {
            file = new OrderFile();
            file.setId(snowFlakeFactory.nextId());
            file.setOrderId(jobDe.getId());
            file.setFileName(outFile.getFileName());
            file.setOriginalFileName(outFile.getOriginalFileName());
            file.setType("OUT");
            file.setUuidName(outFile.getUuidName());
            file.setAbsPath(outFile.getAbsPath());
            orderFileRepository.save(file);
        }

    }

    private String generateNewFilePath(String absPath) {
        File file = new File(absPath);
        String nameNoSuffix = file.getName().substring(0, file.getName().lastIndexOf("."));
        String suffix = file.getName().substring(file.getName().lastIndexOf("."));
        return null;
    }

    public static void main(String[] args) {
        String filePath = "G:\\tianyi\\TY2021B008-1\\In\\SPORTMASTER#TY2021B008-1订单.xlsx";
        File file = new File(filePath);
        System.out.println(file.getName());
        System.out.println(file.getName().substring(file.getName().lastIndexOf(".")));
        System.out.println(file.getName().substring(0, file.getName().lastIndexOf(".")));
    }

    @Override
    public String getFilePathByParams(JobFileQuery jobDetail) {
        JobDetail jobDe = jobDetailRepository.findByOrderNoAndJobName(jobDetail.getOrderNo(), jobDetail.getJobName());
        if (jobDe == null)
            return "";
        List<OrderFile> orderFiles = orderFileRepository.findByOrderId(jobDe.getId());
        for (OrderFile orderFile : orderFiles) {
            if (orderFile.getFileName().equals(jobDetail.getFileName()) && orderFile.getType().equals(jobDetail.getType())) {
                return orderFile.getAbsPath();
            }
        }
        return "";
    }

    @Override
    public List<JobDetailDto> queryByOrderNo(String orderNo) {
        List<JobDetailDto> dtos = new ArrayList<>();
        List<JobDetail> jobDetails = jobDetailRepository.findByOrderNo(orderNo);
        for (JobDetail jobDetail : jobDetails) {
            JobDetailDto dto = new JobDetailDto();
            BeanUtils.copyProperties(jobDetail, dto);
            List<OrderFile> orderFiles = orderFileRepository.findByOrderId(jobDetail.getId());
            for (OrderFile orderFile : orderFiles) {
                JobDetailDto.OrderFileDto fileDto = new JobDetailDto.OrderFileDto();
                BeanUtils.copyProperties(orderFile, fileDto);
                dto.getFileDtos().add(fileDto);
            }
            dtos.add(dto);
        }
        return dtos;
    }

    @Override
    public List<String> queryNos(String params) {
        LocalDate now = LocalDate.now();
        Specification<JobDetail> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.hasText(params) && !"ALL".equals(params.toUpperCase())) {
                Predicate orderNo = criteriaBuilder.like(root.get("orderNo").as(String.class), "%" + params + "%");
                predicates.add(orderNo);
            }
            Predicate timeStart = criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), now.minusMonths(1).atStartOfDay());
            predicates.add(timeStart);
            Predicate timeEnd = criteriaBuilder.lessThan(root.get("createTime"), now.plusDays(1).atStartOfDay());
            predicates.add(timeEnd);
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        List<JobDetail> jobDetails = jobDetailRepository.findAll(specification, sort);
        return jobDetails.stream().map(JobDetail::getOrderNo).distinct().collect(Collectors.toList());
    }
}
